#ifndef __LEXICAL_ANALYZER_H__
#define __LEXICAL_ANALYZER_H__

enum lexical_status
{
	status_success,
	status_eof,
	status_invalid_char,
	status_unknown = -1,
};

enum token_category
{
	token_error,
	token_keyword,
	token_identifier,
	token_number,
	token_char,
	token_string,
	token_operator,
	token_punctuator,
};

struct token
{
	token_category category;
	std::string value;
};

class lexical_analyzer
{
public:
	explicit lexical_analyzer(std::istream& ifs);
	lexical_status get_token(token& t);
	int get_current_line() const;
	int get_current_index() const;
	std::string str;
private:
	bool filter_space();
	bool filter_comment();
	std::string get_hex_string();
	std::string get_digital_string();
	std::string get_string(char delimiter);
	bool is_keyword(const std::string& str);
	int get_char();
	int peek_char();
	void putback(char ch);
	void skip_char();
private:
	std::istream* m_pstream;
	int m_line;
	int m_current_index;
};

inline lexical_analyzer::lexical_analyzer(std::istream& ifs) 
	:m_pstream(&ifs), m_line(1), m_current_index(0)
{
}

inline int lexical_analyzer::get_current_line() const
{
	return m_line;
}

inline int lexical_analyzer::get_current_index() const
{
	return m_current_index;
}

inline int lexical_analyzer::peek_char()
{
	return m_pstream->peek();
}

inline void lexical_analyzer::skip_char()
{
	get_char();
}

#endif // end of __LEXICAL_ANALYZER_H__
